package cn.mill.core.modem;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.mill.common.Builder;
import cn.mill.common.Context;
import cn.mill.common.data.Item;
import cn.mill.common.data.ItemArray;
import cn.mill.core.MillConfig;
import cn.mill.core.utils.NormUtil;

public class ListArraySpell implements FieldSpell, ObjectSpell {
	private static final Logger logger = LoggerFactory.getLogger(ListArraySpell.class);
	
	public static ListArraySpell INSTANCE = new ListArraySpell();
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public <T> T builder(Type type, ItemArray itemArray) {
		if (type != null && itemArray != null) {
			Item[] items = itemArray.getItems();
			if (items != null && items.length > 0) {
				// Item item = items[0];
				// FieldSpell fieldSpell = (FieldSpell)
				// MillConfig.getBuilder(type);
				// return fieldSpell.builder(type, item);
				List ls = this.createList(type, itemArray.getSize());
				for (Item i : itemArray.getItems()) {
					if (i != null) {
						Type beanType = NormUtil.getActualType(type)[0];
						ObjectSpell objectSpell = (ObjectSpell) MillConfig.getBuilder(beanType);
						ls.add(objectSpell.builder(beanType, (ItemArray) i.getValue()));
					}
				}
				return (T) ls;
			}
			return null;
		} else {
			return null;
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public <T> T builder(Type type, Item item) {
		if (type != null && item != null) {
			ItemArray itemArray = (ItemArray) item.getValue();
			List ls = this.createList(type, itemArray.getSize());
			for (Item i : itemArray.getItems()) {
				if (i != null) {
					Type beanType = NormUtil.getActualType(type)[0];
					Builder builder = (Builder) MillConfig.getBuilder(beanType);
					if (builder instanceof BaseSpell) {
						ls.add(((BaseSpell) builder).builder(beanType, i));
					}
					if (builder instanceof ObjectSpell) {
						ls.add(((ObjectSpell) builder).builder(beanType, (ItemArray) i.getValue()));
					}
				}
			}
			return (T) ls;
		}
		return null;
	}
	
	@Override
	public ItemArray resolver(Context context, Type type, Object object) {
		if (object != null) {
			List<?> list = (List<?>) object;
			ItemArray result = new ItemArray(list.size());
			for (int i = 0; i < list.size(); i++) {
				Object o = list.get(i);
				boolean isJavaBean = !NormUtil.isBaseObject(o);
				Type subType = o.getClass();
				if (isJavaBean) {
					ObjectSpell spell = (ObjectSpell) MillConfig.getResolver(subType);
					ItemArray itemArray = spell.resolver(context, subType, o);
					Item item = new Item();
					item.setProperty(null);
					item.setName(i + "");
					item.setValue(itemArray);
					item.setType(subType);
					result.addItem(item, i);
				} else {
					FieldSpell spell = (FieldSpell) MillConfig.getResolver(subType);
					Item item = spell.resolver(context, "", type, o);
					result.addItem(item);
				}
			}
			return result;
		}
		return null;
	}
	
	@Override
	public Item resolver(Context context, String name, Type type, Object object) {
		
		return null;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private <T> List<T> createList(Type type, int size) {
		logger.debug("Create List [" + type + "]" + "=>size:[" + size + "]");
		Object list = new ArrayList(size);
		// return (List<T>)Array.newInstance((Class)type,size);
		return (List) list;
	}
}
